/***********************************************************************************
 * 文件名： polsys_lib.c
 * 作者： 刘言
 * 版本： 1
 * 说明：
 *      常用的一些数据处理相关的宏定义和函数。polsys.h中已经默认包含。
 * 修改记录：
 * 	2021/01/23: 初版。 刘言。
***********************************************************************************/
#include "polsys_lib.h"

// 获取最大值
u16 GetMaxU16(u16 *dat, int len)
{
	int i;
	u16 max = 0;
	for(i=0;i<len;i++)
	{
		if(dat[i]>max)max = dat[i];
	}
	return max;
}

// 波形数据平滑处理，积分运算消除突变
void SmoothWaveU16(u16 *dat, int len)
{
	int i;
	for(i=1;i<len;i++)
	{
		dat[i] = (dat[i] + dat[i-1])/2;
	}
}

// 获得16位绝对值
IN_LINE u16 GetAbsS16(s16 v)
{
	if(v < 0)return -v;
	else return v;
}

// 获得32位校验和
u32 GetSum_U32(const u8 *buff, u32 len)
{
	u32 i;
	u32 sum = 0;
	for (i = 0; i < len; i++)
	{
		sum += buff[i];
	}
	return sum;
}

// 获得8位校验和
u8 GetSum_U8(const u8 *buff, u8 len)
{
	u8 i;
	u8 sum = 0;
	for (i = 0; i < len; i++)
	{
		sum += buff[i];
	}
	return sum;
}

static pdata u32 mRand; // 8bit伪随机数 mRand掉电保存随机性更强
// 生成8bit随机数
u8 GetRand8bit(void)
{
	u32 temp = mRand;
	do
	{
		// 防止为0
		if (temp == 0)
			temp = 0x4B07;
		temp ^= (temp << 13);
		temp ^= (temp >> 17);
		temp ^= (temp << 5);
		mRand = temp;
		temp = (temp >> 16) & 0x00FF;
	} while (temp == 0);
	// 保存mRand;
	return (u8)(temp);
}

bool IsInRangeU16(u16 num, u16 start, u16 end)
{
	return ((num >= start) && (num <= end));
}

////把数据分离成单个字节，高字节在前（0）
//void SplitDWard(u32 a,u8 * b)
//{
//		b[3] = (u8)(a >> 24);
//		b[2] = (u8)(a >> 16);
//		b[1] = (u8)(a >> 8);
//		b[0] = (u8)a;
//}

//把字节数组的成员合并成1个u32整数 0[3] 1[2] 2[1] 3[0]
u32 MakeU32(u8 *Bytes, u8 Lenght)
{
	u8 yw = 0;
	u8 index;
	u32 r = 0;
	u8 i;

	if (Lenght > 4)
		return 0;
	index = Lenght - 1;

	for (i = 0; i < Lenght; i++)
	{
		r += ((u32)Bytes[index] << yw);
		yw += 8;
		index--;
	}
	return r;
}

/****************************************************************************
* 名    称：u8 DecToBcd(u8 dat)
* 功    能：将普通数据转换成高4位存放十位，低4位存放个位的BCD码。
* 入口参数：dat：想要转换的数据
* 出口参数：转换完成的数据
* 说    明：如 55-->0x55
* 调用方法：bcdnum=DecToBcd(num);
****************************************************************************/
u8 DecToBcd(u8 dat)
{
	u8 temp;
	temp = dat / 10;
	dat = dat % 10;
	temp = (temp << 4) + dat;
	return temp;
}
/****************************************************************************
* 名    称：u8 BcdToDec(u8 dat)
* 功    能：将高4位存放十位，低4位存放个位的BCD码转换为普通数据。
* 入口参数：dat：想要转换的数据
* 出口参数：转换完成的数据
* 说    明：如 0x55-->55
* 调用方法：num=BcdToDec(bcdnum);
****************************************************************************/
u8 BcdToDec(u8 dat)
{
	u8 dat1;
	dat1 = dat / 16;
	dat = dat % 16;
	dat1 = dat + dat1 * 10;
	return dat1;
}

/*********************************************************************
* 名    称: u8 MedianFilter8b9(u8 *dat)
* 功    能: 中值滤波
* 入口参数: 数组首地址
* 出口参数: 结果
* 说    明: 8bit 9次
* 调用方法: ADVolue = MedianFilter8b9(datbuff);
**********************************************************************/
u8 MedianFilter8b9(u8 *dat)
{
	u8 i, j, k;
	u8 temp;

	for (i = 0; i < 8; i++) //排序
	{
		k = i;
		for (j = k + 1; j < 9; j++)
		{
			if (dat[k] > dat[j])
				k = j;
		}
		temp = dat[k];
		dat[k] = dat[i];
		dat[i] = temp;
	}
	temp = ((u16)dat[3] + (u16)dat[4] + (u16)dat[5]) / 3; //取中间值
	return (temp);
}

/*********************************************************************
* 名    称: u16 MedianFilter16b9(u16 *dat)
* 功    能: 中值滤波
* 入口参数: 数组首地址
* 出口参数: 结果
* 说    明: 16bit 9次
* 调用方法: ADVolue = MedianFilter16b9(datbuff);
**********************************************************************/
u16 MedianFilter16b9(u16 *dat)
{
	u8 i, j, k;
	u16 temp;

	for (i = 0; i < 8; i++) //排序
	{
		k = i;
		for (j = k + 1; j < 9; j++)
		{
			if (dat[k] > dat[j])
				k = j;
		}
		temp = dat[k];
		dat[k] = dat[i];
		dat[i] = temp;
	}
	temp = ((u32)dat[3] + (u32)dat[4] + (u32)dat[5]) / 3; //取中间值
	return (temp);
}

/*********************************************************************
* 名    称: u16 MedianFilter16b20(u16 *dat)
* 功    能: 中值滤波
* 入口参数: 数组首地址
* 出口参数: 结果
* 说    明: 16bit 20次
* 调用方法: ADVolue = MedianFilter16b20(datbuff);
**********************************************************************/
u16 MedianFilter16b20(u16 *dat)
{
	u8 i, j, k;
	u16 temp;
	u32 add = 0;

	for (i = 0; i < 19; i++) //排序
	{
		k = i;
		for (j = k + 1; j < 20; j++)
		{
			if (dat[k] > dat[j])
				k = j;
		}
		temp = dat[k];
		dat[k] = dat[i];
		dat[i] = temp;
	}
	for(i = 6; i < 14; i++)	// 求和
	{
		add += dat[i];
	}
	temp = add / 8; 	//平均
	return (temp);
}
